//
//  CJExten+StrCode.swift
//  CJCore
//
//  Created by 陈警卫 on 2024-06-14.
//

import Foundation
import CommonCrypto

public extension String {
    
    /// 转Int
    var cj_int: Int {
        guard let value = Double(self) else { return 0 }
        return Int(value)
    }
    
    /// 转Int
    /// 4舍5入
    var cj_intRound: Int {
        guard let value = Double(self) else { return 0 }
        return lround(value)
    }

    /// 转Int
    /// 下取整
    var cj_intFloor: Int {
        guard let value = Double(self) else { return 0 }
        return Int(floor(value))
    }
    
    
    /// 转Int
    /// 上取整
    var cj_intCeil: Int {
        guard let value = Double(self) else { return 0 }
        return Int(ceil(value))
    }
}

public extension String {
    
    /// MD5
    var cj_md5: String? {
        let value = self.cString(using: .utf8)
        let valuelen = CUnsignedInt(lengthOfBytes(using: .utf8))
        let digestlen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestlen)
        guard let value = value else { return nil }
        CC_MD5(value, valuelen, result)
        
        let hash = NSMutableString()
        for i in 0..<digestlen {
            hash.appendFormat("%02x", result[i])
        }
        result.deallocate()
        return hash as String
    }
    
    /// base64编码
    var cj_base64Encode: String {
        guard let data = self.data(using: .utf8) else { return "" }
        return data.base64EncodedString()
    }
    
    /// base64解码
    var cj_base64Decode: String {
        guard let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters) else { return "" }
        return String(data: data, encoding: .utf8) ?? ""
    }
    
    /// URL编码
    var cj_urlEncode: String {
        guard let value = self.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return "" }
        return value
    }
    
    /// URL编码
    var cj_urlEncodeURL: URL? {
        let value = self.cj_urlEncode
        let url = URL(string: value)
        return url
    }
    
    /// URL解码
    func cj_urlDecode() -> String {
        return self.removingPercentEncoding ?? ""
    }
}

public extension String {
    
    /// 转Data encoding 默认.utf8
    func cj_data(encoding: String.Encoding = .utf8) -> Data? {
        return data(using: encoding)
    }
    
    /// 解析JSON
    var cj_dict: Any? {
        return cj_data()?.cj_dict
    }
    
    /// ascii字符串转16进制字符串
    func cj_asciiToHexString() -> String {
        var value = ""
        for us in self.unicodeScalars {
            value.append(String(format: "%02X", us.value))
        }
        return value
    }
    
    /// 转拼音
    func cj_pinyin(_ ton: Bool = false) -> String {
        let value = NSMutableString(string: self)
        CFStringTransform(value, nil, kCFStringTransformToLatin, false)
        if ton {
            CFStringTransform(value, nil, kCFStringTransformStripDiacritics, false)
        }
        return value as String
    }
}

public extension String {
    
    /// 判断是否为16进制字符串
    func cj_isHexString() -> Bool {
        let characterSet = CharacterSet(charactersIn: "0123456789ABCDEFabcdef")
        var value = self.trimmingCharacters(in: characterSet)
        value = value.trimmingCharacters(in: .whitespacesAndNewlines)
        return value.isEmpty
    }
    
    /// 判断是否为2进制字符串
    func cj_isBinaryString() -> Bool {
        let characterSet = CharacterSet(charactersIn: "01")
        var value = self.trimmingCharacters(in: characterSet)
        value = value.trimmingCharacters(in: .whitespacesAndNewlines)
        return value.isEmpty
    }
}

public extension String {
    
    /// 16进制字符串转Data
    var cj_hexData: Data {
        if cj_isHexString() {
            return Data()
        }
        let hexString = replacingOccurrences(of: " ", with: "")
        var hexs = Array<UInt8>()
        for i in 0..<hexString.count where i % 2 == 0 {
            let byteString = hexString.cj_sub(start: i, end: i + 2)
            hexs.append(UInt8(byteString, radix: 16) ?? 0)
        }
        let data = Data(hexs)
        return data
    }
    
    /// 16进制字符串转int
    var cj_hexToInt: Int {
        guard let value = Int(self, radix: 16) else { return 0 }
        return value
    }
    
    /// 16进制字符串转2进制字符串
    var cj_hexToBinary: String {
        if cj_isHexString() {
            return ""
        }
        let rawStr = self.cj_trimAllSpaceAndLines
        var value = ""
        for i in 0..<rawStr.count where i % 2 == 0 {
            let byteString = rawStr.cj_sub(start: i, end: i + 2)
            value.append(String(format: "%08u", UInt8(byteString, radix: 16) ?? 0))
        }
        return value
    }
    
    /// 2进制字符串转int
    var cj_binaryToInt: Int {
        guard let value = Int(self, radix: 2) else { return 0 }
        return value
    }
    
    /// 2进制字符串转16进制字符串
    var cj_binaryToHex: String {
        if cj_isBinaryString() {
            return ""
        }
        let rawStr = self.cj_trimAllSpaceAndLines
        var value = ""
        for i in 0..<rawStr.count where i % 8 == 0 {
            let byteString = rawStr.cj_sub(start: i, end: i + 8)
            value.append(String(format: "%02X", UInt8(byteString, radix: 2) ?? 0))
        }
        return value
    }
    
}
